<?php

/** 
 * Copyright (c) 2012, Jiehun.com.cn Inc. All Rights Reserved
 * @author dengxiaolong@jiehun.com.cn
 * @date 2012-1-15
 * @version 1.0 
 * @brief Imagick
 *  
 **/
require_once dirname(dirname(__FILE__)).'/ImageHandlerInterface.php';

final class ImagickImpl implements ImageHandlerInterface
{
	/**
	 * 压缩图片
	 *
	 * @param string $from
	 * @param string $to
	 * @param int $quality
	 */
	 function compress($from, $to, $quality)
	 {
	 	$imagick = new Imagick($from);
	 	
		$format = $imagick->getImageFormat();
		$imagick->setCompression(Imagick::COMPRESSION_JPEG);
		if ($format == 'GIF') {
			foreach ($imagick as $frame) {  
				$frame->setCompressionQuality($quality);  
				$frame->stripImage();
			}

			$imagick->writeImages($to, true);
		} else {
			$imagick->setCompression(Imagick::COMPRESSION_JPEG);
			$imagick->setCompressionQuality($quality);
			$imagick->stripImage();
			$imagick->writeImage($to);
		}
		$imagick->destroy();
	 }
	 
	 /**
	  * 裁剪图片
	  * 
	  * @param $from 
	  * @param $to
	  * @param $x 裁剪的左边距
	  * @param $y 裁剪的上边距
	  * @param $width 裁剪的宽度
	  * @param $height 裁剪的高度
	  */
	 function crop($from, $to, $x, $y, $width, $height)
	 {
	 	$imagick = new Imagick($from);
	 	$format = $imagick->getImageFormat();
	 	
	 	if ($format == 'GIF') {
 			foreach($imagick as $frame) {
 				$frame->cropImage($width, $height, $x, $y);
 			}
	 		$imagick->writeImages($to, true);
 		} else {
 			$imagick->cropImage($width, $height, $x, $y);
	 		$imagick->writeImage($to);
 		}
 		$imagick->destroy();
	 }

	 /**
	 * 裁剪图片，并保持裁剪后的图片能保留最全的内容
	 *
	 * @param int $width
	 * @param int $height
	 * @param string $from
	 * @param string $to
	 * //TODO 对同一张图片进行同样的操作后，生成的文件md5值不一样
	 */
	 function cropThumb($from, $to, $width, $height)
	 {
	 	$imagick = new Imagick($from);
	 	
	 	$format = $imagick->getImageFormat();
 		if ($format == 'GIF') {
 			foreach($imagick as $frame) {
 				$frame->cropThumbnailImage($width, $height);
 			}
 			$imagick->writeImages($to, true);
 		} else {
 			$imagick->cropThumbnailImage($width, $height);
	 		$imagick->writeImage($to);
 		}
 		$imagick->destroy();
	 }
	 
	 /**
	  * 
	  * 取图片的缩略图，没有达到指定尺寸的部分用背景色填充
	  * @param $from
	  * @param $to
	  * @param $width
	  * @param $height
	  * @param $bgColor
	  */
	 function fillThumb($from, $to, $width, $height, $bgColor = 'white')
	 {
	 	$imagick = new Imagick($from);
	 	
	 	$this->_thumb($imagick, $to, $width, $height);
	 	
	 	$format = $imagick->getImageFormat();
	 	
	 	$geometry = $imagick->getImageGeometry();
	 	$x = ($width - $geometry['width'])/ 2;
	 	$y = ($height - $geometry['height'])/ 2;
	 	
	 	$imgBg = new Imagick();
	 	
	 	if ($format == 'GIF') {
	 		$imgBg->setFormat('gif');
	 		foreach($imagick as $iframe) {
	 			$imgBg->newImage($width, $height, $bgColor, $format);
	 			$imgBg->compositeImage($iframe, Imagick::COMPOSITE_OVER, $x, $y);
	 		}
	 		$imgBg->writeImages($to, true);
	 	} else {
	 		$imgBg->newImage($width, $height, $bgColor, $format);
	 		$imgBg->compositeImage($imagick, Imagick::COMPOSITE_OVER, $x, $y);
	 		$imgBg->writeImage($to);
	 	}
	 	$imagick->destroy();
	 	$imgBg->destroy();
	 }
	 
	 /**
	 * 对图片进行等比例缩放（不会裁剪图片）
	 *
	 * @param string $from
	 * @param string $to
	 * @param int $width
	 * @param int $height
	 */
	 function thumb($from, $to, $width, $height)
	 {
	 	$imagick = new Imagick($from);
	 	if (!$this->_thumb($imagick, $to, $width, $height)) {
	 		copy($from, $to);
	 	}
	 	$imagick->destroy();
	 }
	 
	 /**
	  * 是否需要复制
	  * @param Imagick $imagick
	  * @param string $to
	  * @param int $width
	  * @param int $height
	  * @return boolean
	  */
	 private function _thumb(&$imagick, $to, $width, $height)
	 {
	 	// 如果图片尺寸过小，则不进行缩放
	 	$geometry = $imagick->getImageGeometry();
	 	$format = $imagick->getImageFormat();
	 	if ( (!$width || ($width && $geometry['width'] <= $width)) && ( !$height || ($height && $geometry['height'] <= $height))) {
	 		return false;
	 	}
	 	
	 	if ($format == 'GIF') {
 			foreach($imagick as $frame) {
 				$frame->scaleImage($width, $height, $width && $height);
 			}
 			$imagick->writeImages($to, true);
 		} else {
 			$imagick->scaleImage($width, $height, $width && $height);
	 		$imagick->writeImage($to);
 		}
 		return true;
	 }
	 
	  /**
	  * 对图片进行缩放
	  * 
	  * @param $from
	  * @param $to
	  * @param $rate 缩放比率
	  */
	 function zoom($from, $to, $rate) {
	 	$imagick = new Imagick($from);
	 	$width = $imagick->getImageWidth();
	 	$height = $imagick->getImageHeight();
	 	
		$newWidth = $width * $rate;
		$newHeight = $height * $rate;
		if (!$this->_thumb($imagick, $to, $newWidth, $newHeight)) {
			copy($from, $to);
		}
		
		$imagick->destroy();
	 }
	 
	 /**
	  * 转换图片的格式
	  * @param $from
	  * @param $to
	  * @param $newFormat
	  */
	 function changeFormat($from, $to, $newFormat)
	 {
	 	$imagick = new Imagick($from);
	 	$imagick->setImageFormat($newFormat);
	 	$imagick->writeImage($to);
	 	$imagick->destroy();
	 }
	 
	 /**
	  * 合并图片
	  * @param $imgA
	  * @param $imgB
	  * @param $to
	  * @param $left
	  * @param $top
	  */
	 function merge($imgA, $imgB, $to, $left, $top)
	 {
	 	$imgA = new Imagick($imgA);
	 	$imgB = new Imagick($imgB);
	 	
	 	$format = $imgA->getImageFormat();
	 	if ($format == 'GIF') {
	 		foreach($imgA as $frame) {
	 			$frame->compositeImage($imgB, Imagick::COMPOSITE_OVER, $left, $top);
	 		}
	 		$imgA->writeImages($to, true);
	 	} else {
	 		$imgA->compositeImage($imgB, Imagick::COMPOSITE_OVER, $left, $top);
		 	$imgA->writeImage($to);
	 	}
	 	$imgB->destroy();
 		$imgA->destroy();
	 }
	 
	 /**
	  * 合并图片，支持数组水印和位置数组
	  * @param $imgA
	  * @param $imgB
	  * @param $to
	  * @param $left
	  * @param $top
	  */
	 function mergeByArray($imgA, $imgB, $to, $left, $top)
	 {
	 	$imgA = new Imagick($imgA);
	 
	 	
	 	$format = $imgA->getImageFormat();
	 	$aimgB = null;
	 	for($i=0;$i<count($imgB);$i++){
	 		if($i>0){
	 			if($imgB[$i] != $imgB[$i-1]){
	 				$aimgB->destroy();
	 				$aimgB = new Imagick($imgB[$i]);
	 			}
	 		}else{
	 			$aimgB = new Imagick($imgB[$i]);
	 		}
	 		
	 		
		 	if ($format == 'GIF') {
		 		foreach($imgA as $frame) {
		 			$frame->compositeImage($aimgB, Imagick::COMPOSITE_OVER, $left[$i], $top[$i]);
		 		}
		 	} else {
		 			$imgA->compositeImage($aimgB, Imagick::COMPOSITE_OVER, $left[$i], $top[$i]);			 	
		 	}
		 	
	 	}
	 	
	 	$imgA->writeImage($to);
	 	
 		$imgA->destroy();
	 }
}
